#include "port.h"
#include "gd32f30x.h"
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
#include <stdio.h>

typedef struct {
    uint32_t uartNo;
    rcu_periph_enum rcuUart;
    rcu_periph_enum rcuGpio;
    uint32_t gpio;
    uint32_t txPin;
    uint32_t rxPin;
    uint8_t irq;
} UartHwInfo_t;

static UartHwInfo_t g_uartHwInfo = { USART1, RCU_USART1, RCU_GPIOA, GPIOA, GPIO_PIN_2, GPIO_PIN_3, USART1_IRQn };


static void GpioInit(void)
{
    rcu_periph_clock_enable(g_uartHwInfo.rcuGpio);
    gpio_init(g_uartHwInfo.gpio, GPIO_MODE_AF_PP, GPIO_OSPEED_10MHZ, g_uartHwInfo.txPin);
    gpio_init(g_uartHwInfo.gpio, GPIO_MODE_IPU, GPIO_OSPEED_10MHZ, g_uartHwInfo.rxPin);
}

static void UartInit(uint32_t baudRate)
{
    /* 使能UART时钟；*/
    rcu_periph_clock_enable(g_uartHwInfo.rcuUart);
    /* 复位UART；*/
    usart_deinit(g_uartHwInfo.uartNo);
    /* 通过USART_CTL0寄存器的WL设置字长；*/
    usart_word_length_set(g_uartHwInfo.uartNo, USART_WL_8BIT);
    /* 无校验位；*/
    usart_parity_config(g_uartHwInfo.uartNo, USART_PM_NONE);
    /* 1位停止位；*/
    usart_stop_bit_set(g_uartHwInfo.uartNo, USART_STB_1BIT);
    /* 设置波特率；*/
    usart_baudrate_set(g_uartHwInfo.uartNo, baudRate);
    /* 使能发送功能；*/
    usart_transmit_config(g_uartHwInfo.uartNo, USART_TRANSMIT_ENABLE);
    /*使能接收功能；*/
    usart_receive_config(g_uartHwInfo.uartNo, USART_RECEIVE_ENABLE);
    /* 使能串口中断；*/
    nvic_irq_enable(g_uartHwInfo.irq,5, 0);
    /* 在USART_CTL0寄存器中置位UEN位，使能UART；*/
    usart_enable(g_uartHwInfo.uartNo);

}
// 切换发送接收模式的I/o口
static void SwitchInit(void)
{
    rcu_periph_clock_enable(RCU_GPIOC);                                 //使能GPIOC的时钟
    gpio_init(GPIOC, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5);  //推挽输出
}


/* ----------------------- static functions ---------------------------------*/
static void prvvUARTTxReadyISR(void);
static void prvvUARTRxISR(void);

/* ----------------------- Start implementation -----------------------------*/
void
vMBPortSerialEnable(BOOL xRxEnable, BOOL xTxEnable)
{
    if (TRUE == xRxEnable) {
        usart_interrupt_enable(g_uartHwInfo.uartNo, USART_INT_RBNE);//使能接收中断
        gpio_bit_reset(GPIOC, GPIO_PIN_5);
    } else {
        usart_interrupt_disable(g_uartHwInfo.uartNo, USART_INT_RBNE);//失能接收中断
        gpio_bit_set(GPIOC, GPIO_PIN_5);
    }

    if (TRUE == xTxEnable) {
        usart_interrupt_enable(g_uartHwInfo.uartNo, USART_INT_TC);//使能发送中断   USART_INT_TBE:发送缓冲区为空   USART_INT_TC:传输的移位寄存器为空
        gpio_bit_set(GPIOC, GPIO_PIN_5);
    } else {
        usart_interrupt_disable(g_uartHwInfo.uartNo, USART_INT_TC);//失能发送中断
        gpio_bit_reset(GPIOC, GPIO_PIN_5);
    }
}

BOOL
xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity)
{
    (void)ucPORT;
    (void)ucDataBits;
    (void)eParity;
    SwitchInit();
    GpioInit();
    UartInit(ulBaudRate);
    return TRUE;
}

BOOL
xMBPortSerialPutByte(CHAR ucByte)
{
    usart_data_transmit(g_uartHwInfo.uartNo, ucByte);
    return TRUE;
}

BOOL
xMBPortSerialGetByte(CHAR* pucByte)
{
    *pucByte = usart_data_receive(g_uartHwInfo.uartNo);
	  // printf("%02x ",(uint8_t)*pucByte);
    return TRUE;
}

static void prvvUARTTxReadyISR(void)
{
    pxMBFrameCBTransmitterEmpty();
}


static void prvvUARTRxISR(void)
{
    pxMBFrameCBByteReceived();
}

#ifdef USE_MODBUS_SLAVE
void USART1_IRQHandler(void)
{
    //判断接收还是发送中断
    if (RESET != usart_interrupt_flag_get(g_uartHwInfo.uartNo, USART_INT_FLAG_RBNE)) {
        prvvUARTRxISR();
        usart_interrupt_flag_clear(g_uartHwInfo.uartNo, USART_INT_FLAG_RBNE_ORERR);
    }
    if (RESET != usart_interrupt_flag_get(g_uartHwInfo.uartNo, USART_INT_FLAG_TC)) {
        //发送完成中断
        prvvUARTTxReadyISR();
        usart_interrupt_flag_clear(g_uartHwInfo.uartNo, USART_INT_FLAG_TC);
    }
}
#endif



